home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
msdos
/
dsort
/
dstmain.pre
< prev
next >
Wrap
Text File
|
1991-10-18
|
34KB
|
1,072 lines
page 96,132
;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
;§ §
;§ ディレクトリエントリ ソート ユーティリティ §
;§ §
;§ DSORT.EXE Ver1.11 §
;§ §
;§ Copyright (C) by 福地 邦雄 1991. All rights reserved. §
;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
.MODEL SMALL,C
;
DPB struc
drivenumber db ? ;ドライブ番号
unitnumber db ? ;ユニット番号
sectorlength dw ? ;セクタ長
sectorperalloc db ? ;1クラスタ当たりのセクタ数-1
shiftcount db ? ;1クラスタ当たりのセクタ数の2のべき乗
reservedsector dw ? ;先頭のリザーブセクタ数
numberoffat db ? ;FAT数
directoryentry dw ? ;ルートディレクトリのエントリ数
datastartsector dw ? ;データ領域開始セクタ番号
datasector dw ? ;最大クラスタ数(全クラスタ数+1)
fatsector db ? ;1FAT当たりのセクタ数
directorystart dw ? ;ディレクトリ領域開始セクタ番号
todeviceheader dd ? ;デバイスヘッダへのポインタ
mediadescriptor db ? ;メディアディスクリプタ
diskchange db ? ;ディスクの交換可能属性
tonextdpb dd ? ;次のDPBへのポインタ
currentcluster dw ? ;カレントクラスタ
reserved dw ? ;リザーブ
DPB ends
;
YES equ 1
NO equ 0
FAT12 equ 0ff7h
FAT16 equ 0fff7h
direntrysize equ 20h
;
extrn sweep:word,sortexec:word,recursive:word,dirgather:word
extrn dta:dword,srchname:dword,namebuff:dword,namebuffsiz:word
extrn dirtype:word,fattype:word,attribute:word,clustcount:word
extrn driveno:word,clustsize:word,fatsize:word,dirsize:word
extrn fatbuff:word,dirbuff:word,sortbuff:word,sortcount:word
extrn drvinf:byte,clustsect:word,sectcount:word,fatdrive:word
extrn sortfuncs:word,subchain:word,wildcard:byte,pathbuff:byte
extrn usagemsg:byte,entrycount:word,movecount:word,subsearch:word
extrn procs:byte,dirover:byte,fatover:byte,veralarm:byte,_vermsgsz:abs
extrn bothmsg:byte,sortmsg:byte,movemsg:byte,nothmsg:byte
extrn errorno:word,adjustroot:word
;
extrn getargs:near,options:near,usageout:near,abort:near,dosstdout:near
extrn dirlist:near,dirfind:near,strcopywild:near
extrn dosallocx:near,dirqsort:near,inttoasc0:near
;
PUBLIC main,sortproc,getdirinfo,getdpb,readdirectory,readrootdir
PUBLIC readfat,getfat12chain,getfat16chain,readsubdir,selection
PUBLIC remainsweep,copyback,filldeleted,writedirectory,checkrootsize
PUBLIC dspdirname,dspmsgend,altint23h,critical,breakflag,orgint23h
;
.code
;
;------------------------------------------------------------------------------
; 書き込み時のCtrl+C押下によるディレクトリ破壊を防ぐ処理のワーク
;------------------------------------------------------------------------------
;
critical dw NO
breakflag dw NO
orgint23h dd 0
prgname db 'DirSort',0 ; これは別に意味なし
;
;------------------------------------------------------------------------------
;
; main
; ディレクトリエントリソートユーティリティ メインプログラム
;
; dsort <options> directory name
;
; IN ds & es PSP セグメント
; OUT ?
;
;------------------------------------------------------------------------------
;
main proc near
;
call getargs ; コマンド行パラメータを引き数リストに変換
@if (zf,on)
jmp usageout ; 引き数なしの時はヘルプメッセージ
@ifend
push ax
mov ax,_data ; DS 設定
mov ds,ax
;
mov ah,30h ; DOS バージョンチェック
int 21h
@if (al,>,3) ; 4.00 以上なら未サポート
mov cx,word ptr _vermsgsz
mov dx,offset veralarm
jmp abort
@ifend
;
mov ax,1000h ; ディレクトリ名バッファの獲得
xor dx,dx ; 4KB
call dosallocx
mov word ptr namebuff+2,ax
;
mov ax,3523h ; Ctrl+C ベクタ取得
int 21h
mov word ptr cs:orgint23h,bx
mov word ptr cs:orgint23h+2,es
mov bx,ds ; DS セーブ
mov es,bx
mov ax,2523h ; Ctrl+C ベクタ置き換え
mov dx,offset altint23h ;
mov bx,cs
mov ds,bx
int 21h
mov bx,es ; DS リストア
mov ds,bx
pop ax
;
call options ; 引き数評価&対象ディレクトリリスト作成
@if (sortexec,/=,NO),or,(sweep,/=,NO)
@if (recursive,=,YES) ; 再帰呼び出しをおこなうか?
mov es,word ptr namebuff+2
mov bx,800h ; ディレクトリ名バッファのサイズ変更
mov ah,4ah ; 16KB
int 21h
@if (cf,off)
add namebuffsiz,7000h
@ifend
@ifend
push namebuffsiz ; パラメータセット
push word ptr namebuff
push word ptr namebuff+2
xor ax,ax
push ax
call sortproc ; ディレクトリソート実行
@ifend
;
mov ax,2523h ; Ctrl+C ベクタ復元
lds dx,cs:orgint23h
int 21h
;
mov ah,0dh ; ディスクバッファ リセット
int 21h
;
mov ax,4c00h ; プログラム終了
int 21h
;
main endp
;
;------------------------------------------------------------------------------
;
; sortproc
; ディレクトリソートを実行する
;
; TYPE near call
; IN sp+2:ディレクトリ名リストアドレス
; sp+6:ディレクトリ名バッファの空き領域の先頭
; sp+8:ディレクトリ名バッファの空き領域サイズ
; OUT なし
; 保存レジスタ ds
;
;------------------------------------------------------------------------------
;
sortproc proc near curnameoff,curnameseg,freenameoff,freenamesiz
;
mov di,curnameoff
mov es,curnameseg
@do until
mov entrycount,0 ; 処理したエントリのカウンタを初期化
mov sortcount,0
mov movecount,0
mov ah,0dh ; ディスクバッファ リセット
int 21h
;
call getdirinfo ; ディレクトリ情報獲得
@if (zf,on),L
mov di,curnameoff ; ディレクトリ名表示
mov es,curnameseg
call dspdirname
call readdirectory ; ディレクトリ読み込み
@if (zf,on)
@if (sortexec,=,YES),S
call selection ; ソート対象エントリ取り出し
@if (ax,>,1)
push ds
mov ax,ds
mov es,ax
mov ax,offset sortfuncs
push ax
push sortcount
xor ax,ax
push ax
mov ds,sortbuff
call dirqsort ; クイックソート
pop ds
@ifend
@if (sweep,=,YES)
call remainsweep ; ソート対象外エントリを掻き集める
@ifend
call copyback ; ソートしたエントリを戻す
@else
call predelete
call remainsweep
@ifend
call filldeleted ; 削除エントリの情報をクリアする
mov cs:critical,YES ; クリティカルセクション開始
call writedirectory ; ディレクトリ書き込み
call dspmsgend ; 終了メッセージ表示
mov cs:critical,NO ; クリティカルセクション終了
@if (cs:breakflag,=,YES) ; Ctrl+Cが押下されたので終了
mov errorno,-1
xor cx,cx
xor dx,dx
jmp abort
@ifend
@ifend
@if (recursive,=,YES) ; 再帰呼び出し
mov ah,0dh ; ディスクバッファ リセット
int 21h
;
mov subsearch,YES ;
mov di,curnameoff ; サブディレクトリのリスト獲得
mov es,curnameseg
call strcopywild
mov word ptr srchname,di
mov word ptr srchname+2,es
call dirlist
mov ax,word ptr namebuff
@if (ax,/=,freenameoff) ; サブディレクトリ有りの時
push namebuffsiz
push ax
push word ptr namebuff+2
push freenameoff
call sortproc ; ディレクトリソート再帰実行
@ifend
mov si,freenameoff ; 各ワーク情報を再帰実行から戻す
mov es,freenamesiz
mov namebuffsiz,es
mov word ptr namebuff,si
mov es,curnameseg
mov word ptr es:[si],0
mov subsearch,NO ;
@ifend
@ifend
mov di,curnameoff ; 次の対象ディレクトリへ
mov es,curnameseg
cld
xor ax,ax
mov cx,-1
repne scasb
mov curnameoff,di
@doend (byte ptr es:[di],=,0),L ; ディレクトリリストの終了か?
;
ret 8
;
sortproc endp
;
;------------------------------------------------------------------------------
;
; getdirinfo
; ディレクトリ及びその所属するドライブの情報を獲得する
;
; TYPE near call
; IN ds:di = ディレクトリ名
; OUT drvinf = DPBのコピー その他 ディレクトリ情報
; 保存レジスタ bx,cx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
getdirinfo proc near
;
call dirfind
@if (zf,on)
mov dirtype,ax ; ディレクトリタイプ ルート/サブ
mov subchain,ax ; FATチェインの先頭
mov driveno,dx ; ドライブ番号
dec driveno
;
mov di,offset drvinf ; Drive Parameter Block 取得
call getdpb
;
@if (drvinf.datasector,<=,4086),S ; 12bitFAT/16bitFAT
mov fattype,FAT12 ; v1.00バグ '='が無かった
@else
mov fattype,FAT16
@ifend
xor ax,ax
mov al,drvinf.sectorperalloc
inc ax
mov clustsect,ax ; 1クラスタ当たりのセクタ数
mul drvinf.sectorlength
mov clustsize,ax ; 1クラスタのバイトサイズ
xor ax,ax
@ifend
ret
;
getdirinfo endp
;
;------------------------------------------------------------------------------
;
; getdpb
; ドライブパラメータブロックをコピーする
;
; TYPE near call
; IN dl = ドライブ番号 A:1 B:2 ...
; ds:di = drive parameter block をコピーする領域のアドレス
; OUT ax = 完了コード
; 保存レジスタ bx,cx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
getdpb proc near uses bx cx si di ds es
;
cld
mov ax,ds
mov es,ax
mov ah,32h ; DPBアドレス取得 非公開
mov cx,10h
int 21h
;
mov si,bx
rep movsw ; DPB コピー
ret
;
getdpb endp
;
;------------------------------------------------------------------------------
;
; readdirectory
; ディレクトリを読み込む
;
; TYPE near call
; IN dirtype,driveno,drvinf構造体,fatdrive
; OUT ax = 完了コード entrycount,clustcount
; 保存レジスタ bx,cx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
readdirectory proc near
;
@if (dirtype,=,0),S ; ルートディレクトリ
mov ax,drvinf.directoryentry
@if (ax,<=,2048),S
mov entrycount,ax ; ディレクトリエントリ数 格納
mov adjustroot,NO
call readrootdir
@else
mov entrycount,2048 ; ディレクトリエントリ数を2048とする
mov adjustroot,YES ; ルートのエントリ数評価を遅らせる
call readrootdir
call checkrootsize ; エントリ数評価
@if (zf,off)
mov ah,9 ; ルートディレクトリサイズオーバー表示
mov dx,offset dirover
int 21h
mov ax,-1
jmp rdirerror
@ifend
@ifend
@else
mov ax,driveno ; サブディレクトリ
@if (ax,/=,fatdrive) ; 読み込み済FATと違うドライブ名の時
xor ax,ax ; FATサイズ計算
mov al,drvinf.fatsector
mul drvinf.sectorlength
@if (dx,=,1),and,(ax,=,0),or,(dx,=,0),S
call readfat ; FAT読み込み
@else
mov ah,9 ; FATサイズオーバー表示
mov dx,offset fatover
int 21h
mov ax,-1
jmp rdirerror
@ifend
@ifend
;
cld ; サブディレクトリのクラスタチェインを獲得
mov di,offset subchain
mov es,fatbuff
@if (fattype,=,FAT12),S
call getfat12chain
@else
call getfat16chain
@ifend
mov clustcount,dx ; サブディレクトリのクラスタ数を設定
mov ax,dx
mul clustsize
mov cx,32 ; ディレクトリエントリ数 計算 格納
div cx
@if (ax,<=,2048),S
mov entrycount,ax
call readsubdir ; サブディレクトリ読み込み
@else
mov ah,9 ; ディレクトリサイズオーバー表示
mov dx,offset dirover
int 21h
mov ax,-1
@ifend
@ifend
rdirerror:
test ax,ax
ret
;
readdirectory endp
;
;------------------------------------------------------------------------------
;
; readrootdir
; ルートディレクトリの内容をメモリに読み込む
;
; TYPE near call
; IN drive parameter block 領域 adjustroot
; OUT dirbuff = 読み込んだディレクトリのセグメントアドレス
; 保存レジスタ bp,ds,es
;
;------------------------------------------------------------------------------
;
readrootdir proc near uses bp
;
@if (adjustroot,=,NO),S
mov ax,drvinf.datastartsector ; ディレクトリサイズ計算とメモリ獲得
sub ax,drvinf.directorystart
@else
xor ax,ax ; ルートディレクトリが2048を超えて
mov dx,1 ; いる場合の暫定措置
div drvinf.sectorlength
@ifend
mov sectcount,ax
mul drvinf.sectorlength
mov dirsize,ax
call dosallocx
mov dirbuff,ax
;
push ds ; ルートディレクトリ読み込み
mov ax,driveno
xor bx,bx
mov cx,sectcount
mov dx,drvinf.directorystart
mov ds,dirbuff
int 25h
@if (cf,on)
xor cx,cx
xor dx,dx
jmp abort
@ifend
popf
pop ds
xor ax,ax
ret
;
readrootdir endp
;
;------------------------------------------------------------------------------
;
; checkrootsize
; ルートディレクトリのエントリ数をチェックする
;
; TYPE near call
; IN dirbuff = 読み込んだディレクトリのセグメントアドレス
; OUT ax = 0 ディレクトリ数が範囲内 ax /= 0 範囲オーバー
; 保存レジスタ bx,cx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
checkrootsize proc near uses di es
;
xor di,di ; オフセットを0
mov es,dirbuff ; ディレクトリバッファセグメントを取得
@do until
@if (byte ptr es:[di],=,0) ; 最終エントリを発見したかの判定
xor ax,ax ; 有効+削除エントリが64KB未満(範囲内)
jmp chrtszfind
@ifend
lea di,[di+direntrysize] ; 次のエントリへ
@doend (di,=,0) ; 64KBひとまわりしたか?
mov ax,-1 ; 扱える範囲を超えている
chrtszfind:
test ax,ax
ret
;
checkrootsize endp
;
;------------------------------------------------------------------------------
;
; readfat
; FATを読み込むための領域を獲得し、FATを読み込む
;
; TYPE near call
; IN drive parameter block 領域
; OUT fatbuff = 読み込んだFATのセグメントアドレス
; 保存レジスタ bp,ds,es
;
;------------------------------------------------------------------------------
;
readfat proc near uses bp
;
@if (fatdrive,/=,-1) ; 既に別のFATを読み込み済の時、解放する
mov es,fatbuff
int 21h
mov fatdrive,-1
mov fatbuff,0
@ifend
xor ax,ax ; FAT用領域獲得
mov al,drvinf.fatsector
mul drvinf.sectorlength
call dosallocx
mov fatbuff,ax
;
push ds ; FAT読み込み
mov ax,driveno
mov fatdrive,ax
xor bx,bx
xor cx,cx
mov cl,drvinf.fatsector
mov dx,drvinf.reservedsector
mov ds,fatbuff
int 25h
@if (cf,on)
xor cx,cx
xor dx,dx
jmp abort
@ifend
popf
pop ds
ret
;
readfat endp
;
;------------------------------------------------------------------------------
;
; getfat12chain
; 12ビットFATのチェインをたどって、配列に書き出す。
;
; TYPE near call
; IN es:オフセット0= FAT領域
; ds:di = FATチェインを書き出す配列、 及びその先頭に最初のクラスタ
; 番号を格納しておくこと
; OUT dx = チェインの総クラスタ数
; 保存レジスタ si,bp,ds,es
;
;------------------------------------------------------------------------------
;
getfat12chain proc near
;
mov cl,4
xor dx,dx
@do while,(word ptr [di],<,FAT12)
mov bx,[di]
mov ax,bx
shr ax,1
add bx,ax
mov ax,es:[bx]
@if (word ptr [di],off,1),S
and ax,0fffh
@else
shr ax,cl
@ifend
lea di,[di+2]
mov [di],ax
inc dx
@doend
ret
;
getfat12chain endp
;
;------------------------------------------------------------------------------
;
; getfat16chain
; 16ビットFATのチェインをたどって、配列に書き出す。
;
; TYPE near call
; IN es:オフセット0 = FAT領域
; ds:di = FATチェインを書き出す配列、 及びその先頭に最初のクラスタ
; 番号を格納しておくこと
; OUT dx = チェインの総クラスタ数
; 保存レジスタ cx,si,bp,ds,es
;
;------------------------------------------------------------------------------
;
getfat16chain proc near
;
xor dx,dx
@do while,(word ptr [di],<,FAT16)
mov bx,[di]
shl bx,1
mov ax,es:[bx]
lea di,[di+2]
mov [di],ax
inc dx
@doend
ret
;
getfat16chain endp
;
;------------------------------------------------------------------------------
;
; readsubdir
; サブディレクトリを読み込む
;
; TYPE near call
; IN clustcount ディレクトリのクラスタ数
; OUT dirbuff = 読み込んだディレクトリのセグメントアドレス
; 保存レジスタ cx,si,bp,ds,es
;
;------------------------------------------------------------------------------
;
readsubdir proc near
local cluster:word
;
mov dx,clustcount ; ディレクトリサイズ計算
mov cluster,dx
mov ax,clustsect
mul dx
mul drvinf.sectorlength
mov dirsize,ax
call dosallocx ; ディレクトリバッファ獲得
mov dirbuff,ax
xor bx,bx
mov di,offset subchain ; ディレクトリクラスタチェインの先頭
;
push ds
mov ax,ds
mov es,ax
mov ds,dirbuff
@do until
mov ax,es:[di] ; ディレクトリクラスタ読み込み
sub ax,2
mov cx,es:clustsect
mul cx
add ax,es:drvinf.datastartsector
mov dx,ax
mov ax,es:driveno
push bp
push di
int 25h
@if (cf,on)
xor cx,cx
xor dx,dx
jmp abort
@ifend
popf
pop di
pop bp
add bx,es:clustsize ; 次のバッファオフセット
lea di,[di+2] ; 次のクラスタ
dec cluster ; カウントダウン
@doend (zf,on)
pop ds
xor ax,ax
ret
;
readsubdir endp
;
;------------------------------------------------------------------------------
;
; selection
; 読み込んだディレクトリからattributeで指定されたエントリを選択して
; ソートバッファに移動する
;
; TYPE near call
; IN dirbuff = 読み込んだディレクトリのセグメントアドレス その他
; OUT sortbuff = ソート対象を選択・移動したセグメントアドレス
; 保存レジスタ bp,ds
;
;------------------------------------------------------------------------------
;
selection proc near
;
mov ax,dirsize ; ディレクトリサイズからバッファサイズ
@if (ax,/=,0),S ; 64KB未満
xor dx,dx
@else ; 64KB
mov dx,1
@ifend
call dosallocx ; ソートバッファ獲得
mov sortbuff,ax
mov es,ax
mov bx,attribute ; 選出属性
mov dx,entrycount ; エントリ数
xor si,si
xor di,di
@if (dirtype,/=,0) ; サブディレクトリの時は最初の2つを除外
sub dx,2
mov si,64
@ifend
;
push ds
cld
xor ax,ax
mov ds,dirbuff
@do while,(dx,/=,0),and,(byte ptr [si],/=,0)
@cbegin
@case (byte ptr [si],=,0e5h),S ; 削除エントリか?
mov byte ptr [si],0 ; 後の処理のために0を書いておく
lea si,[si+20h]
@case (byte ptr [si+0bh],on,bl),S ; 属性違いか?
lea si,[si+20h]
@other ; ソートバッファへ移動
mov cx,10h
rep movsw
mov byte ptr [si-20h],0 ; 移動元に0を書いておく
@if (byte ptr [di-20h],=,5) ; 名前の頭がE5用のコードなら戻しておく
mov byte ptr [di-20h],0e5h
@ifend
inc ax ; 移動したエントリ数を加算
@cend
dec dx ; カウントダウン
@doend
pop ds
mov sortcount,ax ; 移動したエントリ数を記録
ret
;
selection endp
;
;------------------------------------------------------------------------------
;
; predelete
; 後のremainsweepルーチンのために削除エントリの先頭を00とする
;
; TYPE near call
; IN entrycount,dirbuff
; OUT なし
; 保存レジスタ ax,bx,dx,si,bp,ds
;
;------------------------------------------------------------------------------
;
predelete proc near
;
mov cx,entrycount
xor di,di
mov es,dirbuff
@do until
@if (byte ptr es:[di],=,0e5h)
mov byte ptr es:[di],0
@ifend
lea di,[di+20h]
dec cx
@doend (zf,on)
ret
;
predelete endp
;
;------------------------------------------------------------------------------
;
; remainsweep
; ソート対象外のエントリをディレクトリバッファの先頭に集める
;
; TYPE near call
; IN entrycount,dirbuff
; OUT movecount
; 保存レジスタ ax,bp,ds
;
;------------------------------------------------------------------------------
;
remainsweep proc near
;
cld
push ds
xor bx,bx
mov dx,entrycount ; ディレクトリのエントリサイズ
mov es,dirbuff
mov ds,dirbuff
xor di,di
@do while,(byte ptr [di],/=,0),and,(dx,/=,0) ; 最初の空きエントリ位置取得
lea di,[di+20h]
dec dx
@doend
mov si,di
@do until
@do while,(byte ptr [si],=,0),and,(dx,/=,0) ; 次の有効エントリ位置取得
lea si,[si+20h]
dec dx
@doend
@if (dx,/=,0) ; 終了でなければエントリを頭へ詰める
inc bx
mov cx,10h
rep movsw
mov byte ptr [si-20h],0 ; 移動元を空きエントリとする
dec dx ; カウントダウン
@do while,(byte ptr [di],/=,0) ; 次の空きエントリ位置取得
lea di,[di+20h]
@doend
@ifend
@doend (dx,=,0)
pop ds
mov movecount,bx ; 移動したエントリ数を記録
ret
;
remainsweep endp
;
;------------------------------------------------------------------------------
;
; copyback
; ソートバッファの内容をディレクトリバッファへ書き戻す
;
; TYPE near call
; IN sortcount,sortbuff,dirbuff
; OUT dirbuff
; 保存レジスタ bx,bp,ds
;
;------------------------------------------------------------------------------
;
copyback proc near uses ds
;
cld
mov dx,sortcount ; ソートバッファ上のエントリ数
mov es,dirbuff
mov ds,sortbuff
xor si,si
xor di,di
@do while,(dx,/=,0)
@if (byte ptr es:[di],=,0),S ; ディレクトリバッファは空きエントリ?
@if (byte ptr [si],=,0e5h) ; 名前の頭がE5なら、変換しておく
mov byte ptr [si],05h
@ifend
mov cx,10h ; コピー
rep movsw
dec dx ; カウントダウン
@else
lea di,[di+20h] ; 次のディレクトリバッファエントリへ
@ifend
@doend
;
mov ax,ds ; ソートバッファの解放
mov es,ax
mov ah,49h
int 21h
;
ret
;
copyback endp
;
;------------------------------------------------------------------------------
;
; filldeleted
; ディレクトリ中の削除エントリをクリアする
;
; TYPE near call
; IN dirsize,dirbuff
; OUT なし
; 保存レジスタ bx,dx,bp,ds
;
;------------------------------------------------------------------------------
;
filldeleted proc near
;
cld
mov ax,0f6h ; 埋め込みデータの設定
mov si,dirsize ; ディレクトリの最終ポイント取得
mov es,dirbuff
@do until
lea si,[si-20h] ; 最終位置から先頭方向へ
@if (byte ptr es:[si],=,0),S ; 削除エントリ判定
mov es:[si],ah ; 頭1バイト 0orE5
mov cx,1fh ; 残り31バイトをF6で埋める
lea di,[si+1]
rep stosb
@else ; 有効エントリが見つかったので
mov ah,0e5h ; それ以後は頭1バイトをE5に変更
@ifend
@doend (si,=,0) ; ディレクトリ先頭になるまで
ret
;
filldeleted endp
;
;------------------------------------------------------------------------------
;
; writedirectory
; ディレクトリバッファをファイルに書き戻す
;
; TYPE near call
; IN dirtype,driveno,drvinf構造体,sectcount,clustcount,dirbuff
; clustsect,clustsize,subchain
; OUT なし
; 保存レジスタ
;
;------------------------------------------------------------------------------
;
writedirectory proc near
local cluster:word
;
@if (dirtype,=,0),S
push ds ; ルートディレクトリ書き込み
mov ax,driveno
xor bx,bx
mov cx,sectcount
mov dx,drvinf.directorystart
mov ds,dirbuff
push bp
int 26h
@if (cf,on)
xor cx,cx
xor dx,dx
jmp abort
@ifend
popf
pop bp
pop ds
@else
push ds ; サブディレクトリ書き込み
mov ax,clustcount
mov cluster,ax
mov di,offset subchain
mov ax,ds
mov es,ax
xor bx,bx
mov ds,dirbuff
@do until
mov ax,es:[di]
sub ax,2
mov cx,es:clustsect
mul cx
add ax,es:drvinf.datastartsector
mov dx,ax
mov ax,es:driveno
push bp
push di
int 26h
@if (cf,on)
xor cx,cx
xor dx,dx
jmp abort
@ifend
popf
pop di
pop bp
add bx,es:clustsize
lea di,[di+2]
dec cluster
@doend (zf,on)
pop ds
@ifend
;
mov es,dirbuff ; ソートバッファの開放
mov ah,49h
int 21h
;
ret
;
writedirectory endp
;
;------------------------------------------------------------------------------
;
; dspdirname
; 処理中ディレクトリ名を表示する
;
; TYPE near call
; IN ES:DI ディレクトリ名文字列アドレス
; OUT なし
; 保存レジスタ DS
;
;------------------------------------------------------------------------------
;
dspdirname proc
;
mov ah,9 ; 処理中メッセージ表示
mov dx,offset procs
int 21h
;
cld ; ディレクトリ名長さを獲得
mov cx,-1
xor ax,ax
mov dx,di
repne scasb
not cx
dec cx
;
push ds ; ディレクトリ名表示
mov ax,es
mov ds,ax
call dosstdout
pop ds
;
mov ah,2 ; 行頭への復帰
mov dl,0dh
int 21h
;
ret
;
dspdirname endp
;
;------------------------------------------------------------------------------
;
; dspmsgend
; 処理終了メッセージを表示する
;
; TYPE near call
; IN sortcount,movecount,sortproc,sweep
; OUT なし
; 保存レジスタ ax,bx,cx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
dspmsgend proc uses ax bx cx dx si di ds es
local wrks:dword,wrka:word
;
mov ax,sortcount ; ソートしたエントリ数
mov bx,movecount ; 移動したエントリ数
mov cx,ax
add cx,bx
@cbegin
@case (sortexec,=,YES),and,(sweep,=,YES),and,(cx,/=,0),S ; ソート&移動
mov ax,cx
mov si,offset bothmsg
@case (sortexec,=,YES),and,(sweep,=,NO),and,(ax,/=,0),S ; ソートのみ
@if (ax,>,1),S
mov si,offset sortmsg ; 2つ以上ならソートのみ表示
@else
mov si,offset bothmsg ; 1つだけならソート&移動表示
@ifend
@case (sortexec,=,NO),and,(sweep,=,YES),and,(bx,/=,0),S ; 移動のみ
mov ax,cx
mov si,offset movemsg ; 移動
@other
xor ax,ax
mov si,offset nothmsg ; 対象なし
@cend
@if (ax,/=,0)
mov di,ss ; 処理したエントリ数表示
mov es,di
lea di,offset wrka+1
call inttoasc0
lea di,[di-5] ; 0サプレス処理
push di
mov cx,4
@do while,(byte ptr es:[di],=,'0'),and,(cx,/=,0)
mov byte ptr es:[di],' '
inc di
dec cx
@doend
mov cx,5 ; エントリ数表示
pop dx
mov di,ds
push ss
pop ds
call dosstdout
mov ds,di
@ifend
mov ah,9 ; エントリ数に続くメッセージ表示
mov dx,si
int 21h
ret
;
dspmsgend endp
;
;------------------------------------------------------------------------------
;
; altint23h
; Ctrl+C押下の横取り
;
; TYPE interrupt
; IN なし
; OUT なし
; 保存レジスタ ax,bx,cx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
altint23h proc
;
@if (cs:critical,=,NO),S ; クリティカルセクションではない時
jmp cs:orgint23h ; 既存の終了処理へ
@else ; クリティカルセクションの時
mov cs:breakflag,YES ; Ctrl+C押下を記憶しただけで復帰
iret
@ifend
;
altint23h endp
;
end main